package com.yeskery.nut.core;

import com.yeskery.nut.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;

/**
 * url资源对象
 * @author YESKERY
 * 2024/8/13
 */
public class UrlResource implements FileResource {

    /** url地址 */
    private final String url;

    /**
     * 构建url资源对象
     * @param url url地址
     */
    public UrlResource(String url) {
        this.url = url;
    }

    @Override
    public boolean exists() {
        try {
            HttpURLConnection connection = (HttpURLConnection) getURL().openConnection();
            if (connection == null) {
                return false;
            }
            connection.setRequestMethod(Method.HEAD.name());
            int code = connection.getResponseCode();
            if (code == HttpURLConnection.HTTP_OK) {
                return true;
            } else if (code == HttpURLConnection.HTTP_NOT_FOUND) {
                return false;
            }
            if (connection.getContentLengthLong() > 0) {
                return true;
            }
            getInputStream().close();
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    @Override
    public URI getURI() {
        try {
            return getURL().toURI();
        } catch (URISyntaxException e) {
            throw new NutException("UrlResource URI Obtain Fail.", e);
        }
    }

    @Override
    public URL getURL() {
        try {
            return new URL(url);
        } catch (MalformedURLException e) {
            throw new NutException("UrlResource URL Obtain Fail.", e);
        }
    }

    @Override
    public File getFile() {
        throw new NutException("UrlResource Not Support File System.");
    }

    @Override
    public long lastModified() {
        try {
            HttpURLConnection connection = (HttpURLConnection) getURL().openConnection();
            connection.setRequestMethod(Method.HEAD.name());
            return connection.getLastModified();
        } catch (IOException e) {
            throw new NutException("UrlResource[" + url + "] Connect Fail.");
        }
    }

    @Override
    public boolean isReadable() {
        try {
            HttpURLConnection connection = (HttpURLConnection) getURL().openConnection();
            connection.setRequestMethod(Method.HEAD.name());
            int code = connection.getResponseCode();
            if (code != HttpURLConnection.HTTP_OK) {
                connection.disconnect();
                return false;
            }
            long contentLength = connection.getContentLengthLong();
            if (contentLength > 0) {
                return true;
            } else if (contentLength == 0) {
                return false;
            } else {
                getInputStream().close();
                return true;
            }
        } catch (IOException e) {
            return false;
        }
    }

    @Override
    public boolean isOpen() {
        return false;
    }

    @Override
    public boolean isFile() {
        return false;
    }

    @Override
    public InputStream getInputStream() {
        try {
            HttpURLConnection connection = (HttpURLConnection) getURL().openConnection();
            return connection.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String getName() {
        return StringUtils.getFilename(url);
    }

    @Override
    public Long length() {
        try {
            HttpURLConnection connection = (HttpURLConnection) getURL().openConnection();
            connection.setRequestMethod(Method.HEAD.name());
            return connection.getContentLengthLong();
        } catch (IOException e) {
            throw new NutException("UrlResource[" + url + "] Connect Fail.");
        }
    }
}
